package com.example.sanguogameserver.service;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.sanguogameserver.consts.SanGuoConst;
import com.example.sanguogameserver.entity.ContactGroup;
import com.example.sanguogameserver.entity.Friend;
import com.example.sanguogameserver.entity.GroupPlayer;
import com.example.sanguogameserver.entity.Player;
import com.example.sanguogameserver.enums.DingTypeEnum;
import com.example.sanguogameserver.enums.GroupPlayerTypeEnum;
import com.example.sanguogameserver.mapper.ContactGroupMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.sanguogameserver.request.CreateGroupReq;
import com.example.sanguogameserver.request.PullPlayerGroupReq;
import com.example.sanguogameserver.response.GroupListResp;
import com.example.sanguogameserver.response.GroupPlayerResp;
import com.example.sanguogameserver.util.AuthUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 群组表 服务实现类
 * </p>
 *
 * @author baomidou
 * @since 2024-03-28
 */
@Service
public class ContactGroupService extends ServiceImpl<ContactGroupMapper, ContactGroup> implements IService<ContactGroup> {

    @Autowired
    private PlayerService playerService;
    @Autowired
    private GroupPlayerService groupPlayerService;
    @Autowired
    private FriendService friendService;

    public List<GroupListResp> listByPlayerId(Integer currPlayerId) {
        List<GroupListResp> groupListResps = baseMapper.listByPlayerId(currPlayerId);
        groupListResps.forEach(item -> {
            item.setGroupHeads(getGroupHead(item.getGroupHeads()));
            item.setPlayers(null);
        });
        return groupListResps;
    }

    private List<GroupPlayerResp> getGroupHead(List<GroupPlayerResp> groupPlayerResps) {
        return groupPlayerResps.stream().sorted((Comparator.comparing(GroupPlayerResp::getGroupPlayerCreateTime))).limit(SanGuoConst.groupHeadNum).toList();
    }

    /**
     * 创建群聊
     *
     * @return
     */
    @Transactional
    public GroupListResp create(CreateGroupReq createGroupReq) {
        List<Integer> playerIds = createGroupReq.getPlayerIds();
        Player currentPlayer = playerService.getById(AuthUtil.getCurrPlayerId());
        // 校验是否是好友
        List<Friend> friends = friendService.isFriends(AuthUtil.getCurrPlayerId(), playerIds);
        Assert.isTrue(friends.size() == playerIds.size(), "有人不是好友");

        List<Player> players = playerIds.stream().map(playerId -> playerService.getById(playerId)).toList();
        players.addFirst(currentPlayer);
        String groupName = players.stream().limit(SanGuoConst.groupHeadNum).map(Player::getPlayName).collect(Collectors.joining(", ")) + "的群聊";

        ContactGroup contactGroup = new ContactGroup();
        contactGroup.setGroupId(IdUtil.simpleUUID());
        contactGroup.setGroupName(groupName);
        contactGroup.setCreateTime(LocalDateTime.now());
        save(contactGroup);
        List<GroupPlayer> groupPlayers = getGroupPlayers(players, contactGroup, currentPlayer);
        groupPlayerService.saveBatch(groupPlayers);

        GroupListResp groupListResp = baseMapper.getById(contactGroup.getId());
        groupListResp.setGroupHeads(getGroupHead(groupListResp.getGroupHeads()));
        return groupListResp;
    }

    public void pullPlayer(PullPlayerGroupReq pullPlayerGroupReq) {
        List<Integer> playerIds = pullPlayerGroupReq.getPlayerIds();
        // 校验是否是好友
        List<Friend> friends = friendService.isFriends(AuthUtil.getCurrPlayerId(), playerIds);
        Assert.isTrue(friends.size() == playerIds.size(), "有人不是好友");
        List<Player> players = playerIds.stream().map(playerId -> playerService.getById(playerId)).toList();
        ContactGroup contactGroup = getById(pullPlayerGroupReq.getGroupId());
        List<GroupPlayer> groupPlayers = getGroupPlayers(players, contactGroup, null);
        groupPlayerService.saveBatch(groupPlayers);
    }

    private static List<GroupPlayer> getGroupPlayers(List<Player> players, ContactGroup contactGroup, Player currentPlayer) {
        return players.stream().map(player -> {
            GroupPlayer groupPlayer = new GroupPlayer();
            groupPlayer.setGroupId(contactGroup.getGroupId());
            groupPlayer.setGroupName(contactGroup.getGroupName());
            groupPlayer.setPlayerId(player.getId());
            groupPlayer.setPlayerName(player.getPlayName());
            if (currentPlayer != null && player == currentPlayer)
                groupPlayer.setGroupPlayerType(GroupPlayerTypeEnum.groupMaster);
            else groupPlayer.setGroupPlayerType(GroupPlayerTypeEnum.ordinary);
            groupPlayer.setDingType(DingTypeEnum.normal);
            groupPlayer.setCreateTime(LocalDateTime.now());
            return groupPlayer;
        }).toList();
    }

    public GroupListResp detailById(Integer id) {
        GroupListResp groupListResp = baseMapper.getById(id);
        groupListResp.setGroupHeads(getGroupHead(groupListResp.getGroupHeads()));
        return groupListResp;
    }
}
